#!/usr/bin/env python
# -*- coding: utf-8 -*-

#SNAKE - jogo clássico em python, implementação pedagógica
#Copyright (C) 2008  <João S. O. Bueno>

#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.


#Authors:  João S. O. Bueno

import pygame
from copy import copy
from random import randrange

import snake
from snake import PAREDE, VAZIO, COBRA_CORPO, COBRA_CABECA, COBRA_CAUDA, MACA

TELA = None #variável global, mantendo a superficie da Tela do jogo

class GameMapa(snake.Mapa):
    def __init__(self, janela, largura, altura):
        self.janela = janela
        snake.Mapa.__init__(self, largura, altura)
        self.larg_celula = janela.largura // self.largura
        self.alt_celula = janela.altura // self.altura
        self.carrega_imagens()
        self.mapa_anterior = snake.Mapa(largura,altura)
        self.counter = 0
    def carrega_imagens(self):
        l = pygame.image.load
        self.imagens = {PAREDE: l("parede.png"),
                        VAZIO: l("quadrado_preto.png"),
                        COBRA_CORPO: l("esfera_1.png"),
                        COBRA_CABECA: l("esfera_2.png"),
                        COBRA_CAUDA: l("esfera_1.png"),
                        MACA: l("esfera_2.png")
                       }

    def mantem_mapa_anterior(self):
        self.mapa_anterior.data = copy(self.data)

    def desenha(self):
        for y in range(self.altura):
            for x in range(self.largura):
                if self.counter != 0 and self[x, y] == self.mapa_anterior[x, y]:
                    continue
                imagem = self.imagens[self[x,y]]
                i_x = x * self.larg_celula
                i_y =  y  * self.alt_celula
                TELA.blit(imagem, (i_x, i_y))
        self.mantem_mapa_anterior()
        self.counter += 1


class Som(object):
    """Envelopa um arquivo de som no disco, e lhe entrega um metodo "play"
    como o do pyglet.
    """
    #sons sao um pouquinho chatos no pygame, por que temos que achar qual
    #canal está livre antes de toca-lo
    def __init__(self, arquivo):
        self.som = pygame.mixer.Sound(arquivo)
        self.num_canais = pygame.mixer.get_num_channels()
        self.canais = []
        for i in range(self.num_canais):
            self.canais.append(pygame.mixer.find_channel(i))
    def play(self):
        #sons sao um pouquinho chatos no pygame, por que temos que achar qual
        #canal está livre antes de toca-lo
        ocupado = pygame.mixer.get_busy()
        c = 0
        while True:
            if not ocupado % 2:
                break
            c += 1
            ocupado >>= 1
        if c < self.num_canais:
            self.canais[c].play(self.som)

class Game(snake.Game):
    #used keyboard constants, on method "on_key" at snake.Game:
    K_RIGHT = pygame.K_RIGHT
    K_LEFT = pygame.K_LEFT
    K_DOWN = pygame.K_DOWN
    K_UP = pygame.K_UP
    K_ESCAPE = pygame.K_ESCAPE
    K_SPACE = pygame.K_SPACE

    def __init__(self, largura, altura, *args, **kwargs):
        global TELA
        snake.Game.__init__(self, largura, altura, *args, **kwargs)
        TELA = pygame.display.set_mode((largura,altura))

    def inicializa_jogo(self):
        snake.Game.inicializa_jogo(self, GameMapa)

    def laco_principal(self):
        while True:
            pygame.time.wait(50)
            eventos = self.agenda.keys()
            while (self.agenda and pygame.time.get_ticks() > min(self.agenda.keys())):
                chave_evento = min(self.agenda.keys())
                self.agenda[chave_evento]()
                del self.agenda[chave_evento]
            pygame.event.pump ()
            eventos = pygame.event.get()
            for evento in eventos:
                if evento.type == pygame.KEYDOWN:
                    self.on_key_press(evento.key)
            self.atualiza()

    def carrega_sons(self):
        snake.Game.carrega_sons(self)
        for evento, arquivo in self.sons.items():
            self.sons[evento] = Som(arquivo)

    def atualiza(self, relogio=0):
        snake.Game.atualiza(self, relogio)
        self.on_draw()
        pygame.display.flip()

    def cria_placar(self):
        self.texto_placar = "%d pontos!" % self.pontos
        self.fonte = pygame.font.Font("FreeSans.ttf", 80)

    def atualiza_placar(self):
            cor = (255, 255, 10 * self.contador % 255)
            imagem_placar = self.fonte.render(self.texto_placar, True, cor)
            TELA.blit(imagem_placar,
                      (self.largura // 2 - imagem_placar.get_width() //2,
                       self.altura // 2 - imagem_placar.get_height() //2))

    def comeu_maca(self, pos):
        snake.Game.comeu_maca(self, pos)
        self.agenda[pygame.time.get_ticks() + 1000] = self.nova_maca

    def encerrar(self):
        pygame.quit()


pygame.init()
game = Game(800,600)
game.laco_principal()